/**
 * 
 */
package com.I9lou.se.lurker.remote;

import org.apache.lucene.document.Field.Index;
import org.apache.lucene.document.Field.Store;

/**
 * 可索引的字段对象。
 * 由于Lucene3.0.3及之前的版本中的NumericField 不支持序列化，
 * 所以只能用自己的类来进行封装
 * @author chenwei
 * @date 2011-03-30
 */
public class IndexableField implements java.io.Serializable {
	
	private static final long serialVersionUID = 2086812843121167911L;

	/**
	 * 字段名称
	 */
	private String name = "";
	
	/**
	 * 字段值
	 */
	private Object value = "";
	
	/**
	 * 字段是否为数字类型
	 */
	private boolean numeric = false;
	
	/**
	 * 该字段是否仅用于排序，只有当字段为数字类型时才起效
	 */
	private boolean sortOnly = false;
	
	/**
	 * 字段存储类型
	 */
	private Store store;
	
	/**
	 * 索引类型，该值对数字类型的字段不起作用
	 */
	private Index index;
	
	/**
	 * 字段权重值，默认为1.0
	 */
	private float boost = 1.0f;
	
	public IndexableField() {
		super();
	}
	
	public IndexableField(String name, Store store) {
		super();
		this.name = name;
		this.store = store;
	}

	public IndexableField(String name, Store store,
			Index index) {
		this(name, store);
		this.index = index;
	}
	
	public IndexableField(String name, Store store,
						  Index index, float boost) {
		this(name, store, index);
		this.boost = boost;
		this.index = index;
	}

	/**
	 * 获得字段名称
	 * @return name
	 */
	public String getName() {
		return name;
	}

	/**
	 * 设置字段名称
	 * @param name
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * 以字符串类型获取字段值
	 * @return stringValue
	 */
	public String getStringValue() {
		try {
			return (String)value;
		} catch(Exception e) {
			throw new IllegalArgumentException("Incorrect field: " + name, e);
		}
	}
	
	/**
	 * 以Long类型获取字段值
	 * @return longValue
	 */
	public Long getLongValue() {
		try {
			return (Long)value;
		} catch(Exception e) {
			throw new IllegalArgumentException("Incorrect field: " + name, e);
		}
	}
	
	/**
	 * 以Integer类型获取字段值
	 * @return intValue
	 */
	public Integer getIntValue() {
		try {
			return (Integer)value;
		} catch(Exception e) {
			throw new IllegalArgumentException("Incorrect field: " + name, e);
		}
	}
	
	/**
	 * 以Float类型获取字段值
	 * @return floatValue
	 */
	public Float getFloatValue() {
		try {
			return (Float)value;
		} catch(Exception e) {
			throw new IllegalArgumentException("Incorrect field: " + name, e);
		}
	}
	
	/**
	 * 以Double类型获取字段值
	 * @return doubleValue
	 */
	public Double getDoubleValue() {
		try {
			return (Double)value;
		} catch(Exception e) {
			throw new IllegalArgumentException("Incorrect field: " + name, e);
		}
	}
	
	/**
	 * 以Object类型获取字段值，通常在外部知道该值类型的情况下调用
	 * @return value
	 */
	public Object getValue() {
		return value;
	}

	/**
	 * 以字符串类型设置字段值
	 * @param value
	 * @return this
	 */
	public IndexableField setStringValue(String value) {
		this.value = value;
		this.numeric = false;
		return this;
	}
	
	/**
	 * 以Long类型设置字段值
	 * @param value
	 * @return this
	 */
	public IndexableField setLongValue(Long value) {
		this.value = value;
		this.numeric = true;
		return this;
	}
	
	/**
	 * 以Integer类型设置字段值
	 * @param value
	 * @return this
	 */
	public IndexableField setIntValue(Integer value) {
		this.value = value;
		this.numeric = true;
		return this;
	}
	
	/**
	 * 以Float类型设置字段值
	 * @param value
	 * @return this
	 */
	public IndexableField setFloatValue(Float value) {
		this.value = value;
		this.numeric = true;
		return this;
	}
	
	/**
	 * 以Double类型设置字段值
	 * @param value
	 * @return this
	 */
	public IndexableField setDoubleValue(Double value) {
		this.value = value;
		this.numeric = true;
		return this;
	}

	/**
	 * 判断当前字段是否为数字类型字段
	 * @return isNumeric
	 */
	public boolean isNumeric() {
		return numeric;
	}
	
	/**
	 * 判断当前字段是否为Long类型字段
	 * @return isLong
	 */
	public boolean isLong() {
		return value instanceof Long;
	}
	
	/**
	 * 判断当前字段是否为Int类型字段
	 * @return isInt
	 */
	public boolean isInt() {
		return value instanceof Integer;
	}
	
	/**
	 * 判断当前字段是否为Float类型字段
	 * @return isFloat
	 */
	public boolean isFloat() {
		return value instanceof Float;
	}
	
	/**
	 * 判断当前字段是否为Double类型字段
	 * @return isDouble
	 */
	public boolean isDouble() {
		return value instanceof Double;
	}
	
	/**
	 * 判断该字段是否仅用于排序，只有当字段为数字类型时才起效
	 * @return sortOnly
	 */
	public boolean isSortOnly() {
		return sortOnly;
	}

	/**
	 * 设置该字段是否仅用于排序，只有当字段为数字类型时才起效
	 * @param sortOnly
	 */
	public void setSortOnly(boolean sortOnly) {
		this.sortOnly = sortOnly;
	}

	/**
	 * 获得该字段存储类型
	 * @return store
	 */
	public Store getStore() {
		return store;
	}

	/**
	 * 设置该字段存储类型
	 * @param store
	 */
	public void setStore(Store store) {
		this.store = store;
	}

	/**
	 * 获得该字段索引类型，该值对数字类型的字段不起作用
	 * @return index
	 */
	public Index getIndex() {
		return index;
	}

	/**
	 * 设置该字段索引类型，该值对数字类型的字段不起作用
	 * @param index
	 */
	public void setIndex(Index index) {
		this.index = index;
	}
	
	/**
	 * 获得该字段权重值
	 * @return boost
	 */
	public float getBoost() {
		return boost;
	}

	/**
	 * 设置该字段权重值，默认为1.0
	 * @param boost
	 */
	public void setBoost(float boost) {
		this.boost = boost;
	}

	@Override
	public String toString() {
		StringBuilder buffer = new StringBuilder("IndexableField@{");
		buffer.append("name: \"").append( getName() );
		buffer.append("\", value: \"").append( value );
		buffer.append("\", index: \"").append( getIndex() );
		buffer.append("\", store: \"").append( getStore() );
		buffer.append("\", numeric: \"").append( isNumeric() );
		buffer.append("\", boost: \"").append( getBoost() );
		return buffer.append("\"}").toString();
	}
	
}
